package cz.cuni.mff.ufal.volk;

import cz.cuni.mff.ufal.volk.utils.ByteArray;

/**
 * Recorded speech in a natural language.
 *
 * <p>Common formats are:
 * <table border="1">
 *  <tr><td><b>Id</b></td><td><b>Description</b></td></tr>
 *  <tr><td>wav/signed-integer</td><td>WAVE format</td></tr>
 *  <tr><td>wav/oki-adpcm</td><td>WAVE format encoded with ADPCM2 codec</td></tr>
 *  <tr><td>mp3</td><td>mp3</td></tr>
 * </table>
 * </p>
 *
 * @author Bartłomiej Etenkowski
 */
public class Speech implements Expression {

  private static final long serialVersionUID = 8648954755975418560L;

  /**
   * Constructs a new Speech object.
   *
   * @param  language the language of the speech. It can be {@code null} if the language
   *         is not known yet.
   * @param  the format of the data
   * @param  data the binary data
   *
   * @throws NullPointerException if the {@code data} or {@code format} parameter
   *         is {@code null}
   */
  public Speech(String language, String format, byte[] data) {
    data.getClass();
    format.getClass();
    this.language = language;
    this.format = format;
    this.data = new ByteArray(data);
  }

  /**
   * Constructs a new Speech object with the specified data.
   *
   * @param  language the language of the speech
   * @param  the format of the binary data
   * @param  data the underlying binary data
   *
   * @throws NullPointerException if the {@code data} or {@code format} parameter
   *         is {@code null}
   */
  public Speech(String language, String format, ByteArray data) {
    data.getClass();
    format.getClass();
    this.language = language;
    this.format = format;
    this.data = data;
  }

  private final String language;
  private final String format;
  private final ByteArray data;

  /**
   * Returns the language of the sound.
   * @return the language of the sound
   */
  @Override
  public String getLanguage() {
    return language;
  }

  /**
   * Returns the underlying binary data of the sound.
   * @return the underlying binary data of the sound
   */
  public ByteArray getData() {
    return data;
  }

  /**
   * Returns the format of the data.
   * @return the format of the underlying data
   */
  public String getFormat() {
    return format;
  }

  /**
   * Returns a {@code Speech} object with the specified language. The underlying binary data
   * is shared between the old and the new object, therefore, the method is efficient.
   * @param  language
   * @return
   */
  public Speech specifyLanguage(String language) {
    return new Speech(language, this.format, this.data);
  }

}
